package service

import (
	"ai/internal/db/models"
	"ai/internal/repository"
	"math/rand"
	"time"
)

type ActivityService struct {
	activityRepo *repository.ActivityRepository
	questionRepo *repository.QuestionRepository
}

func NewActivityService(activityRepo *repository.ActivityRepository, questionRepo *repository.QuestionRepository) *ActivityService {
	return &ActivityService{activityRepo: activityRepo, questionRepo: questionRepo}
}

func (s *ActivityService) StartPractice(userID uint, questionType string) error {
	questions, err := s.questionRepo.GetQuestionsByType(questionType)
	if err != nil {
		return err
	}

	activity := &models.Activity{
		UserID:    userID,
		Type:      models.Practice,
		Questions: questions,
	}

	return s.activityRepo.CreateActivity(activity)
}

func (s *ActivityService) StartExam(userID uint) error {
	singleChoiceQuestions, err := s.questionRepo.GetQuestionsByType("single_choice")
	if err != nil {
		return err
	}

	multipleChoiceQuestions, err := s.questionRepo.GetQuestionsByType("multiple_choice")
	if err != nil {
		return err
	}

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	r.Shuffle(len(singleChoiceQuestions), func(i, j int) {
		singleChoiceQuestions[i], singleChoiceQuestions[j] = singleChoiceQuestions[j], singleChoiceQuestions[i]
	})
	r.Shuffle(len(multipleChoiceQuestions), func(i, j int) {
		multipleChoiceQuestions[i], multipleChoiceQuestions[j] = multipleChoiceQuestions[j], multipleChoiceQuestions[i]
	})

	activity := &models.Activity{
		UserID:    userID,
		Type:      models.Exam,
		Questions: append(singleChoiceQuestions[:40], append(singleChoiceQuestions[40:180], multipleChoiceQuestions[:10]...)...),
	}

	return s.activityRepo.CreateActivity(activity)
}

func (s *ActivityService) RecordWrongQuestion(userID, questionID uint, keep bool) error {
	wrongSet := &models.WrongSet{
		UserID:     userID,
		QuestionID: questionID,
		Keep:       keep,
	}
	return s.activityRepo.AddToWrongSet(wrongSet)
}

func (s *ActivityService) GetWrongSet(userID uint) ([]models.WrongSet, error) {
	return s.activityRepo.GetWrongSetByUser(userID)
}

func (s *ActivityService) ResolveWrongQuestion(userID, questionID uint) error {
	return s.activityRepo.ResolveWrongQuestion(userID, questionID)
}

func (s *ActivityService) UpdateQuestionStatus(userID, questionID uint, status models.QuestionStatus) error {
	return s.activityRepo.UpdateQuestionStatus(userID, questionID, status)
}

func (s *ActivityService) GetQuestionsByStatus(userID uint, status models.QuestionStatus) ([]models.Question, error) {
	return s.activityRepo.GetQuestionsByStatus(userID, status)
}
